﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;

namespace Drive_Caffeine {
    public partial class MainWindow : Form {

        private const string TOOLTIP_APPNAME = "Drive Caffeine";

        private List<SimpleDrive> ActiveDrives = new List<SimpleDrive>();

        public MainWindow() {
            InitializeComponent();

            this.Text = String.Format("Drive Caffeine v{0}.{1}",
                                      Assembly.GetExecutingAssembly().GetName().Version.Major,
                                      Assembly.GetExecutingAssembly().GetName().Version.Minor);

            // Set options based on saved settings.
            if (Properties.Settings.Default.MinimiseToSystemTrayOnStartup) {
                OptionsMenuMinimiseToSystemTrayOnStartup.Checked = true;
                MinimiseToSystemTray();
            }

            // Populate drive list.
            DriveInfo[] allDrives = DriveInfo.GetDrives();
            bool isSaved = false;
            foreach (DriveInfo drive in allDrives) {
                if (drive.DriveType == DriveType.Fixed || drive.DriveType == DriveType.Removable) {
                    SimpleDrive newDrive = new SimpleDrive(drive);
                    isSaved = Properties.Settings.Default.DriveList.Contains(newDrive.ToString());
                    DriveList.Items.Add(newDrive, isSaved ? CheckState.Checked : CheckState.Unchecked);

                    if (isSaved) {
                        ActiveDrives.Add(newDrive);
                    }
                }
            }

            UpdateSystemTrayTooltipWithDriveLetters();

            // Set poll interval from saved settings if it's saved, otherwise take it from the GUI.
            if (Properties.Settings.Default.WakeupInterval > 0) {
                WakeupTimer.Interval = Properties.Settings.Default.WakeupInterval;
                WakeupIntervalSpinner.Value = Properties.Settings.Default.WakeupInterval / 1000 / 60;
            } else {
                WakeupTimer.Interval = GetInterval();
            }

            #if DEBUG
                WakeupTimer.Interval = 7000; // 7s for debug.
                Console.WriteLine("In debug mode.");
            #endif

            WakeupTimer.Start();
        }

        private int GetInterval() {
            return (int)WakeupIntervalSpinner.Value * 60 * 1000;
        }

        private void MinimiseToSystemTray() {
            if (!Properties.Settings.Default.MinimisedToSystemTrayBubbleAlreadyShown) {
                SystemTrayIcon.ShowBalloonTip(10000);
                Properties.Settings.Default.MinimisedToSystemTrayBubbleAlreadyShown = true;
                Properties.Settings.Default.Save();
            }
            this.WindowState = FormWindowState.Minimized;
            this.ShowInTaskbar = false;
            this.Hide();
        }

        private void UpdateSystemTrayTooltipWithDriveLetters() {
            // How's that for a descriptive function name? ;)
            if (ActiveDrives.Count < 1) {
                // USER: Y U NO CHECK ANY DRIVES?
                SystemTrayIcon.Text = TOOLTIP_APPNAME + " - No drives selected";
                return;
            }

            StringBuilder tooltip = new StringBuilder(TOOLTIP_APPNAME + " - Running on ");
            foreach (SimpleDrive drive in ActiveDrives) {
                tooltip.Append(drive.RootPath);
                // If it's not the last drive in the list...
                if (!(ActiveDrives.IndexOf(drive) == ActiveDrives.Count - 1)) {
                    tooltip.Append(", ");
                }
            }

            SystemTrayIcon.Text = tooltip.ToString();
        }

        private void MainWindow_Resize(object sender, EventArgs e) {
            if (WindowState == FormWindowState.Minimized) {
                MinimiseToSystemTray();
            }
        }

        private void SystemTrayExit_Click(object sender, EventArgs e) {
            Application.Exit();
        }

        private void SystemTrayIcon_MouseClick(object sender, MouseEventArgs e) {
            if (e.Button == MouseButtons.Left) {
                this.Show();
                this.WindowState = FormWindowState.Normal;
                this.ShowInTaskbar = true;
            }
        }

        private void SystemTrayOpen_Click(object sender, EventArgs e) {
            this.Show();
            this.WindowState = FormWindowState.Normal;
        }

        private void FileMenuExit_Click(object sender, EventArgs e) {
            Application.Exit();
        }

        private void WakeupTimer_Tick(object sender, EventArgs e) {
            // Write a blank file to the target disk, then delete it again.
            string fileName = "drive_caffeine_wakeup_file";
            foreach (SimpleDrive drive in DriveList.CheckedItems) {
                try {
                    string filePath = drive.RootPath + fileName;
                    #if DEBUG
                        Console.WriteLine("Writing file to {0}...", drive.RootPath);
                    #endif
                    StreamWriter f = File.CreateText(filePath);
                    f.WriteLine("You may safely delete this file at any time :)");
                    f.Close();
                    #if DEBUG
                        Console.WriteLine("Deleting file from {0}...", drive.RootPath);
                    #endif
                    File.Delete(filePath);
                }
                catch (IOException) {
                    // TODO: Do something better here, seriously.
                }
            }
        }

        private void WakeupIntervalSpinner_ValueChanged(object sender, EventArgs e) {
            WakeupTimer.Stop();
            WakeupTimer.Interval = GetInterval();
            Properties.Settings.Default.WakeupInterval = WakeupTimer.Interval;
            Properties.Settings.Default.Save();
            WakeupTimer.Start();
        }

        private void DriveList_ItemCheck(object sender, ItemCheckEventArgs e) {
            if (DriveList.SelectedItem != null) {
                string driveID = DriveList.SelectedItem.ToString();

                if (e.NewValue == CheckState.Checked) {
                    Properties.Settings.Default.DriveList.Add(driveID);
                    ActiveDrives.Add((SimpleDrive)DriveList.SelectedItem);
                } else {
                    Properties.Settings.Default.DriveList.Remove(driveID);
                    ActiveDrives.Remove((SimpleDrive)DriveList.SelectedItem);
                }

                Properties.Settings.Default.Save();

                UpdateSystemTrayTooltipWithDriveLetters();
            }
        }

        private void HelpMenuCodePlex_Click(object sender, EventArgs e) {
            System.Diagnostics.Process.Start("http://drivecaffeine.codeplex.com/");
        }

        private void HelpMenuAbout_Click(object sender, EventArgs e) {
            AboutDialog dialog = new AboutDialog();
            dialog.ShowDialog();
        }

        private void SystemTrayPause_CheckedChanged(object sender, EventArgs e) {
            if (SystemTrayPause.Checked) {
                WakeupTimer.Stop();
                SystemTrayIcon.Text = TOOLTIP_APPNAME + " - Paused";
            } else {
                WakeupTimer.Start();
                UpdateSystemTrayTooltipWithDriveLetters();
            }
        }

        private void OptionsMenuMinimiseToSystemTrayOnStartup_CheckStateChanged(object sender, EventArgs e) {
            Properties.Settings.Default.MinimiseToSystemTrayOnStartup = OptionsMenuMinimiseToSystemTrayOnStartup.Checked;
            Properties.Settings.Default.Save();
        }
    }
}
